package tests;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet;


import model.MediaProperty;
import model.MediaType;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

public class MediaTypeTest {
	
	MediaType defaultType;
	MediaType image;
	MediaType audio;
	MediaType video;
	ArrayList<String> defaultPropertiesName;
	ArrayList<String> imagePropertiesName;
	ArrayList<String> videoPropertiesName;
	ArrayList<String> audioPropertiesName;
	
	private final LocalServiceTestHelper helper =
	            new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
	
	@Before
	public void setUp() {
		helper.setUp();		
		defaultPropertiesName = new ArrayList<String>(Arrays.asList("name","key","size"));
		imagePropertiesName = new ArrayList<String>(Arrays.asList("name","key","size","title","desc"));
		videoPropertiesName = new ArrayList<String>(Arrays.asList("name","key","size","title","artist","actor","genre","desc"));
		audioPropertiesName = new ArrayList<String>(Arrays.asList("name","key","size","title","artist","album","genre"));
		defaultType = new MediaType("","");
		image = new MediaType("image","Images");
		audio = new MediaType("audio","Audio");
		video = new MediaType("video","Videos");		
	}
	
	@After
	public void tearDown() {
		helper.tearDown();
	}

	private Object[] toArray(TreeSet<MediaProperty> allMediaProperties) {
		ArrayList<String> result = new ArrayList<String>();
		for (MediaProperty mp : allMediaProperties) {
			result.add(mp.name);
		}
		return (Object[]) result.toArray();
	}
	
	@Test
	public void testGetMediaTypeWithNullType() {
		MediaType testNullType = MediaType.getMediaType(null);
		assertEquals("", testNullType.name);
		checkArrayEqualNoOrder(defaultPropertiesName.toArray(), toArray(testNullType.getAllMediaProperties()));
	}
	
	@Test
	public void testGetMediaTypeWithDefaultType() {				
		MediaType testNoType = MediaType.getMediaType("");		
		assertEquals("", testNoType.name);
		checkArrayEqualNoOrder(defaultPropertiesName.toArray(), toArray(testNoType.getAllMediaProperties()));
		assertEquals("name", testNoType.getMediaProperty("name").name);
		assertEquals(null, testNoType.getMediaProperty("actor"));
	}
	
	@Test
	public void testGetMediaTypeWithArbitrayType() {
		MediaType testAnyType = MediaType.getMediaType("something");
		assertEquals("", testAnyType.name);
		checkArrayEqualNoOrder(defaultPropertiesName.toArray(), toArray(testAnyType.getAllMediaProperties()));
		assertEquals("size", testAnyType.getMediaProperty("size").name);
		assertEquals(null, testAnyType.getMediaProperty("title"));
	}
	

	@Test
	public void testGetMediaTypeWithImageType() {
		MediaType testImageType = MediaType.getMediaType("image");
		assertEquals("image", testImageType.name);
		checkArrayEqualNoOrder(imagePropertiesName.toArray(), toArray(testImageType.getAllMediaProperties()));
		assertEquals("title", testImageType.getMediaProperty("title").name);
		assertEquals("key", testImageType.getMediaProperty("key").name);
	}
	
	@Test
	public void testGetMediaTypeWithVideoType() {
		MediaType testVideoType = MediaType.getMediaType("video");
		assertEquals("video", testVideoType.name);
		checkArrayEqualNoOrder(videoPropertiesName.toArray(), toArray(testVideoType.getAllMediaProperties()));
		assertEquals("actor", testVideoType.getMediaProperty("actor").name);
		assertEquals("desc", testVideoType.getMediaProperty("desc").name);		
	}

	@Test
	public void testGetMediaTypeWithAudioType() {
		MediaType testAudioType = MediaType.getMediaType("audio");
		assertEquals("audio", testAudioType.name);
		checkArrayEqualNoOrder(audioPropertiesName.toArray(), toArray(testAudioType.getAllMediaProperties()));
		assertEquals("size", testAudioType.getMediaProperty("size").name);
		assertEquals("album", testAudioType.getMediaProperty("album").name);
		assertEquals("genre", testAudioType.getMediaProperty("genre").name);		
	}

	private void checkArrayEqualNoOrder(Object[] array, Object[] array2) {
		Arrays.sort(array);
		Arrays.sort(array2);
		assertArrayEquals(array, array2);		
	}

}
